﻿#include <iostream>
#include <string>
using namespace std;
/* 对象结构型模式
1.意图
将抽象部分与它的实现部分分离，使它们都可以独立地变化
2.别名
Handle/Body
3.适用性
a.你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为，在程序运行时刻实现部分应可以被选择或切换
b.类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合，并
分别对它们进行扩充
c.对一个抽象的实现部分的修改应对客户不产生影响，即客户的代码不必重新编译
d.（C++）你想对客户完全隐藏抽象的实现部分。在C++中，类的表示在类接口中是可见的
e.正如在意图一节的第一个类图中所示的那样，有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。Runbaugh称
这种类层次结构为"嵌套的普化"nested generalizations
f.你想在多个对象间共享实现（可能使用引用计数），但同时要求客户并不知道这一点。
*/
class Color
{
public:
	virtual void FillColor() = 0;
};

class Red :public Color
{
public:
	Red():pcolor("红色") {}
	void FillColor()
	{
		cout << "填充颜色：" << pcolor << endl;
	}
private:
	string pcolor;
};

class Blue :public Color
{
public:
	Blue() :pcolor("蓝色") {}
	void FillColor()
	{
		cout << "填充颜色：" << pcolor << endl;
	}
private:
	string pcolor;
};

class Shape
{
public:
	virtual void ShowShape() = 0;
	virtual void SetColor(Color*  color) = 0;
protected:
	virtual void DrawShape() = 0;
	virtual void DrawColor() = 0;
	Color* color;
};
class Circle:public Shape
{
public:
	Circle():shapeType("Circle"){}
	void ShowShape()
	{
		DrawShape();
		DrawColor();
	}
	void SetColor(Color* color)
	{
		this->color = color;
	}
private:
	void DrawShape()
	{
		cout << "绘制：" << shapeType << endl;
	}
	void DrawColor()
	{
		this->color->FillColor();
	}
	string shapeType;
};

class Rect :public Shape
{
public:
	Rect():shapeType("矩形"){}
	void ShowShape()
	{
		DrawShape();
		DrawColor();
	}
	void SetColor(Color* color)
	{
		this->color = color;
	}
private:
	void DrawShape()
	{
		cout << "绘制：" << shapeType << endl;
	}
	void DrawColor()
	{
		this->color->FillColor();
	}
	string shapeType;
};
/*
int main()
{
	Shape* pshape = new Circle;
	pshape->SetColor(new Red);
	pshape->ShowShape();
	pshape->SetColor(new Blue);
	pshape->ShowShape();
	delete pshape;
	pshape = new Rect;
	pshape->SetColor(new Red);
	pshape->ShowShape();
	pshape->SetColor(new Blue);
	pshape->ShowShape();
	delete pshape;

	return 0;
}
*/